home *** CD-ROM | disk | FTP | other *** search
/ Giga Pack / Giga Pack CD1.iso / cards / labelle3 / labelle3.bas < prev    next >
BASIC Source File  |  1989-09-16  |  14KB  |  349 lines

  1. 'La Belle Lucie by George Leotti, July 1988
  2. 'Revised by Robert Gellman, November 1988
  3. 'Second revision by R. G., September 1989
  4.  
  5. 'The original program was written in Microsoft's QuickBASIC 4.0.
  6. 'This version is in QuickBASIC 4.5, but it uses routines from the
  7. 'PROBAS library of programming tools.  If you want to modify the
  8. 'code but don't have PROBAS, use the original version.
  9. 'PROBAS is a product of Hammerly Computer Services.
  10.  
  11. DEFINT A-Z
  12. CONST true = -1, false = NOT true
  13. DECLARE SUB Initial () : DECLARE SUB DisplayCards ()
  14. DECLARE SUB Shuffle () : DECLARE SUB FindCard (r, x, w, flag)
  15. DECLARE SUB Arrow (rr, cc, erasearrow)
  16. COMMON SHARED r$, s$, cards, m$, dsegh, dofsh, back
  17. DIM SHARED deck(52), pile(24), colr(3), scrnh(2000), scrn(2000)
  18.  
  19. xcolor = SCREEN(1, 1, 1): CALL Initial
  20.  
  21. Newgame:                                       'reset for new game
  22. COLOR 15, back: CLS : cards = 52: deal = 2: done = 0
  23. tag$ = "(Q)uit (H)elp (S)huffle"
  24. FOR i = 1 TO 52: deck(i) = i: NEXT: ERASE pile
  25. LOCATE 2, 7: PRINT "La Belle Lucie"; TAB(59); "Deal    Cards"
  26. PRINT TAB(60); deal; TAB(68); cards
  27. CALL Shuffle: CALL DisplayCards                'shuffle and deal
  28.  
  29. Mainloop:
  30. IF cards = 0 THEN GOTO endhand                 'a winner
  31. LOCATE 24, (40 - (LEN(tag$) / 2)), 1: PRINT tag$;
  32. freemove = false: uploop = false               'flag last shuffle move
  33. GOSUB Getinput                                 'get input
  34. IF rank < 1 THEN bad = 1: GOTO badmove
  35.  
  36. Movecard:
  37. CALL FindCard(rank, x, w, 0)
  38. IF w = 0 THEN
  39.    IF uploop THEN                              'If cycling foundation
  40.       CALL DisplayCards: GOTO Mainloop         'cards, no error
  41.    ELSE
  42.       bad = 2: GOTO badmove                    'card not available
  43.    END IF
  44. END IF
  45.  
  46. okaytomove:
  47. IF rank - suit * 13 > 1 THEN                   'move non-aces
  48.    FOR i = 20 TO 23
  49.        IF rank - pile(i) = 1 AND suit = pile(i) \ 13 THEN
  50.           pile(i) = rank: EXIT FOR
  51.        END IF
  52.    NEXT
  53. ELSE                                           'move aces
  54.    FOR i = 20 TO 23
  55.        IF pile(i) = 0 THEN pile(i) = rank: EXIT FOR
  56.    NEXT
  57. END IF
  58. IF rank = pile(i) THEN                         'foundation card found
  59.    pile(w) = pile(w) - 1: cards = cards - 1: deck(x) = 0
  60.    FOR j = x TO cards: SWAP deck(j), deck(j + 1): NEXT
  61.    col = 28 + 6 * (i - 20): r = rank - suit * 13
  62.    COLOR colr(suit), 7                         'display foundation
  63.    LOCATE 1, col: PRINT MID$(r$, r, 1); "    "
  64.    LOCATE 2, col: PRINT CHR$(3 + suit); "    "
  65.    LOCATE 3, col: PRINT "    "; CHR$(3 + suit)
  66.    LOCATE 4, col: PRINT "    "; MID$(r$, r, 1)
  67.    IF r = 13 THEN
  68.       COLOR , back: LOCATE 3, 9 + 2 * (i - 20)
  69.       PRINT CHR$(3 + suit): done = done + 1    'done=completed suit
  70.    END IF
  71.    IF pile(w) = 0 THEN                         'fix hole in tableau
  72.       FOR i = w TO 18: SWAP pile(i), pile(i + 1): NEXT
  73.    END IF
  74.    COLOR 15, back: LOCATE 3, 68: PRINT cards
  75.    IF rank - suit * 13 < 13 THEN               'do range if not king
  76.       uploop = true                            'internal cycle flag
  77.       rank = rank + 1: GOTO Movecard           'do next card in range
  78.    END IF
  79.    CALL DisplayCards: GOTO Mainloop
  80. END IF                                         'end foundation move
  81.  
  82.                                                'move card in tableau
  83. flag = 1: CALL FindCard(rank1, x1, w1, flag)
  84. IF flag THEN bad = flag: GOTO badmove
  85. pile(w1) = pile(w1) + 1                        'adjust piles
  86. pile(w) = pile(w) - 1
  87. IF x > x1 THEN                                 'move card down in deck
  88.    FOR i = x TO x1 + 2 STEP -1
  89.       SWAP deck(i - 1), deck(i)
  90.    NEXT
  91. ELSE                                           'move card up in deck
  92.    FOR i = x TO x1 - 1
  93.        SWAP deck(i + 1), deck(i)
  94.    NEXT
  95. END IF
  96. IF pile(w) = 0 THEN                            'fix hole in tableau
  97.    FOR i = w TO 18: SWAP pile(i), pile(i + 1): NEXT
  98. END IF
  99. LOCATE 3, 68: PRINT cards
  100. CALL DisplayCards: GOTO Mainloop               'end tableau move
  101.  
  102. Lastshuffle:                     
  103. freemove = true                                'set freemove flag
  104. LOCATE 24, 20: CALL clreol
  105. LOCATE , 33, 1: PRINT tag$;
  106. GOSUB Getinput
  107.  
  108. x = 0: IF rank < 1 THEN bad = 1: GOTO badmove
  109. FOR i = 1 TO cards                             'find card
  110.    IF deck(i) = rank THEN
  111.       x = i: w = x \ 3 + 1 + (x / 3 = x \ 3): EXIT FOR
  112.    END IF
  113. NEXT
  114. IF x = 0 THEN bad = 1: GOTO badmove
  115. GOTO okaytomove
  116.  
  117. Getinput:                        
  118. LOCATE 22, 7: CALL clreol: m$ = ""
  119. IF freemove THEN                               'after last shuffle
  120.    COLOR 31: SOUND 5000, .5
  121.    PRINT "Enter a card to draw or move "; : COLOR 15
  122. ELSE PRINT "   What is your move ";
  123. END IF
  124. DO:
  125.    CALL getkey(0, i, j, j, j): z$ = UCASE$(CHR$(i))
  126.    SELECT CASE z$
  127.       CASE CHR$(13): EXIT DO
  128.       CASE CHR$(8)
  129.          IF m$ <> "" THEN
  130.             CALL bkspace(row, col): LOCATE row, col
  131.             m$ = LEFT$(m$, LEN(m$) - 1)
  132.          END IF
  133.       CASE ELSE
  134.          IF INSTR(r$ + s$, z$) <> 0 THEN
  135.             PRINT z$; : m$ = m$ + z$: IF LEN(m$) > 2 THEN EXIT DO
  136.          END IF
  137.     END SELECT
  138. LOOP
  139.  
  140. LOCATE 22, 7, 0: CALL clreol
  141. SELECT CASE m$
  142.    CASE "Q": GOTO endhand
  143.    CASE "N": GOTO Mainloop                              'help screen
  144.    CASE "H"
  145.       dseg = VARSEG(scrn(1)): dofs = VARPTR(scrn(1))
  146.       CALL dgetscreen(dseg, dofs, 1, 1, 25, 80, 0, 0)   'save screen
  147.       CALL dputscreen(dsegh, dofsh, 1, 1, 25, 80, 0, 0) 'get help
  148.       CALL getkey(0, i, i, i, i)                        'wait for key
  149.       CALL dputscreen(dseg, dofs, 1, 1, 25, 80, 0, 0)   'restore
  150.       LOCATE , , 1: GOTO Getinput
  151.    CASE "S"
  152.       IF deal = 0 THEN
  153.          IF freemove THEN GOTO Getinput ELSE bad = 7: GOTO badmove
  154.       END IF
  155.       CALL Shuffle: deal = deal - 1: LOCATE 3, 60: PRINT deal
  156.       CALL DisplayCards
  157.       IF deal = 0 THEN tag$ = LEFT$(tag$, 14): GOTO Lastshuffle
  158.       GOTO Mainloop
  159.    CASE ELSE
  160.       IF LEN(m$) <> 2 THEN bad = 3: GOTO badmove
  161. 'convert input to deck notation                'r is from; r1 is to
  162.       rank = INSTR(r$, LEFT$(m$, 1))           'get rank
  163.       IF rank = 0 THEN RETURN                  'error
  164.       suit = INSTR(s$, MID$(m$, 2, 1)) - 1     'get suit
  165.       rank = suit * 13 + rank                  'value of card, 1-52
  166.       rank1 = rank + 1
  167. END SELECT
  168. RETURN                                         'end of getinput
  169.  
  170. badmove:                                       'display errors
  171. LOCATE 22, 7: CALL clreol: SOUND 5000, .5
  172. SELECT CASE bad
  173.    CASE 1, 3: PRINT "I don't understand your input."
  174.    CASE 7: PRINT "No shuffles left!"
  175.    CASE ELSE: PRINT "That card can't be moved."
  176.               CALL Arrow(rr, cc, erasearrow)   'show card location
  177. END SELECT
  178. CALL delay18th(20)                             'wait 1 second +
  179. IF erasearrow THEN LOCATE rr, cc: PRINT " ": COLOR 15, back
  180. IF freemove THEN GOTO Lastshuffle              'if move available
  181. GOTO Mainloop
  182.  
  183. endhand:
  184. FOR i = 6 TO 25: LOCATE i, 1: CALL clreol: NEXT
  185. IF cards = 0 THEN                               'game won
  186.    won = won + 1: bonus = 10: LOCATE 3, 9
  187.    FOR j = 1 TO deal + 1
  188.        FOR i = 1 TO 5: SOUND 500 * i, .6: NEXT
  189.    NEXT
  190.    FOR i = 20 TO 23                             'flash suit symbols
  191.        j = pile(i) \ 13 - 1: COLOR 16 + colr(j)
  192.        PRINT CHR$(3 + j); " ";
  193.    NEXT: COLOR 15
  194. ELSE lost = lost + 1
  195. END IF
  196.  
  197. score = done * 20 + 52 - (cards + done * 13) + bonus * deal
  198. totalscore = totalscore + score
  199. LOCATE 8, 27: PRINT "Score for this game is"; STR$(score)
  200. LOCATE 10, 23: PRINT "You've won"; won; "game";
  201. PRINT STRING$(ABS(won > 1 OR won = 0), 115); " and lost"; lost;
  202. PRINT "game"; STRING$(ABS(lost > 1 OR lost = 0), 115);
  203. left = left + cards: average! = left / (won + lost)
  204. avgscore! = totalscore / (won + lost)
  205. LOCATE 12, 23: PRINT "Average score this session is ";
  206. PRINT USING "###.#"; avgscore!
  207. LOCATE 14, 23: PRINT "Average number of cards left is ";
  208. PRINT USING "##.#"; average!
  209.  
  210. IF cards > 0 THEN LOCATE 18, 27: PRINT "Hit R to resume last game"
  211. LOCATE 20, 29: PRINT "Hit Q to return to DOS"
  212. LOCATE 22, 24: PRINT "Hit any other key for a new game"
  213. CALL getkey(0, i, j, j, j)
  214. SELECT CASE UCASE$(CHR$(i))
  215.   CASE "Q": COLOR xcolor MOD 16, xcolor \ 16: CLS : LOCATE , , 1: END
  216.   CASE "R": lost = lost - 1: left = left - cards
  217.             totalscore = totalscore - score
  218.             CALL DisplayCards: IF freemove THEN GOTO Lastshuffle
  219.             LOCATE 24, (40 - (LEN(tag$) / 2)), 1: PRINT tag$;
  220.             GOTO Getinput
  221.   CASE ELSE: bonus = 0: GOTO Newgame
  222. END SELECT                                     'end endhand
  223.  
  224. DATA "   The object is to move all cards from the tableau to the"
  225. DATA "foundation in ascending order, Ace through King by suit.",""
  226. DATA "   18 piles are dealt to the tableau.  17 piles of 3 cards, and"
  227. DATA "1 pile with 1 card.  Move cards within the tableau by suit in"
  228. DATA "descending order (e.g. 7S on the 8S).  Only the TOP (right-most)"
  229. DATA "card in a pile can be moved either to a foundation or to another"
  230. DATA "tableau pile.  Kings can only be moved to the foundation.",""
  231. DATA "   Designate moves with two characters.  For example, '7S' means"
  232. DATA "move 7 of Spades.  The computer will first try a foundation pile"
  233. DATA "and then the tableau.  If the 7 can go on a foundation, the"
  234. DATA "computer will automatically move the 8,9, etc, if available.",""
  235. DATA "   You are allowed two reshuffles.  On the final shuffle, you may"
  236. DATA "move ONE card from ANYWHERE in a tableau pile to the foundation,"
  237. DATA "OR to a top card in the tableau according to the above rules. "
  238. DATA "Enter an 'S' at the prompt to shuffle the cards.",""
  239. DATA "   Enter 10's as 'T', Jacks as 'J', Queens as 'Q', Kings as 'K'."
  240.  
  241. SUB Arrow (rr, cc, erasearrow) STATIC
  242. i = 1: x = pile(1): c = 1: row = 6: col = 10: erasearrow = false
  243. DO WHILE x
  244.    FOR j = 0 TO x - 1: d = deck(c + j)         'get card number
  245.       suit = d \ 13 + (d \ 13 = d / 13)        'change it to suit
  246.       z$ = MID$(r$, d - suit * 13, 1)          '& rank
  247.       IF z$ = LEFT$(m$, 1) THEN
  248.          IF INSTR(s$, (MID$(m$, 2, 1))) - 1 = suit THEN
  249.              erasearrow = true: COLOR 31: rr = row - 1: cc = col + j
  250.              LOCATE rr, cc: PRINT ""; : EXIT SUB
  251.          END IF
  252.       END IF
  253.    NEXT
  254.    i = i + 1: col = col + 5 + x: c = c + j: x = pile(i)
  255.    IF col + x + 4 > 75 THEN col = 10: row = row + 5
  256. LOOP
  257. END SUB
  258.  
  259. SUB DisplayCards STATIC                        'display tableau
  260. FOR i = 6 TO 20: LOCATE i, 1: CALL clreol: NEXT
  261. i = 1: x = pile(1): c = 1: row = 6: col = 10
  262. DO WHILE x
  263.    FOR j = 0 TO x - 1: d = deck(c + j)         'get card number
  264.       suit = d \ 13 + (d \ 13 = d / 13)        'change it to suit
  265.       m$ = MID$(r$, d - suit * 13, 1)          '& rank
  266.       COLOR colr(suit), 7
  267.       LOCATE row, col + j: PRINT m$            'print it (upper left)
  268.       LOCATE row + 1, col + j: PRINT CHR$(3 + suit)
  269.    NEXT: x$ = STRING$(3 + x, 32)
  270.    LOCATE row, col + j: PRINT "    "           'display rest of pile.
  271.    LOCATE row + 1, col + j: PRINT "    "
  272.    LOCATE row + 2, col: PRINT x$; CHR$(3 + suit)
  273.    LOCATE row + 3, col: PRINT x$; m$
  274.    i = i + 1: col = col + 5 + x: c = c + j: x = pile(i)
  275.    IF col + x + 4 > 75 THEN col = 10: row = row + 5
  276. LOOP
  277. COLOR 15, back
  278. END SUB
  279.  
  280. SUB FindCard (r, x, w, flag) STATIC
  281. SHARED rank, suit
  282. x = 0: w = 0
  283. FOR i = 1 TO 18                                'check top card for
  284.    x = x + pile(i)                             'a match with r
  285.    IF deck(x) = r THEN w = i: EXIT FOR
  286. NEXT
  287. IF flag = 0 THEN EXIT SUB ELSE flag = 0
  288. IF w = 0 OR rank - suit * 13 = 13 THEN flag = 2
  289. END SUB
  290.  
  291. SUB Initial STATIC
  292. 'initialize colors; create virtual help screen
  293.  
  294. r$ = "A23456789TJQK": s$ = "HDCS"
  295. colr(0) = 4: colr(1) = 4: back = 2: CALL getcrt(i)
  296. red = 36: black = 32: blue = 31: yellow = 30: hue = true
  297. IF NOT i OR INSTR(COMMAND$, "B") <> 0 THEN
  298.    ERASE colr: hue = false
  299.    back = 0: red = 15: black = 15: blue = 15: yellow = 15
  300. END IF
  301.  
  302. 'create virtual screen to hold help screen
  303. dsegh = VARSEG(scrnh(1)): dofsh = VARPTR(scrnh(1))
  304. CALL dclear(dsegh, dofsh, blue)                'clear virtual screen
  305. z$ = "How to play La Belle Lucie"
  306. i = 0: j = 15: IF hue THEN i = 1: j = 14
  307. CALL dwindowmanager(dsegh, dofsh, 2, 2, 24, 79, 2, 15, i, 0, 0, j, z$)
  308. FOR i = 3 TO 22                                'write to virtual screen
  309.     READ z$: CALL dxqprint(dsegh, dofsh, z$, i, 8, blue)
  310. NEXT
  311. z$ = "<Hit any key to continue>"
  312. CALL dxqprint(dsegh, dofsh, z$, 24, 27, yellow) 'write last line
  313.  
  314. COLOR 15, back: CLS : RANDOMIZE TIMER          'opening screen
  315. CALL bigprint(CHR$(6), CHR$(6), 8, 5, black)
  316. CALL bigprint(CHR$(3), CHR$(3), 9, 19, red)
  317. CALL bigprint(CHR$(4), CHR$(4), 9, 54, red)
  318. CALL bigprint(CHR$(5), CHR$(5), 8, 68, black)
  319. LOCATE 24, 29: PRINT "Press any key to begin";
  320. COLOR 15: IF hue THEN COLOR 0
  321. LOCATE 18, 62: c = 2
  322. PRINT "Programmed by": LOCATE , 62: PRINT "George Leotti"
  323. LOCATE , 62: PRINT "Modified by": LOCATE , 62: PRINT "Robert Gellman"
  324. LOCATE , 62: PRINT "Rel. 3.0  9/89"
  325. IF hue THEN
  326.    COLOR 15, 0: LOCATE 24, 12
  327.    PRINT "To suppress color, exit and restart like this: LABELLE/B";
  328.    DO: LOCATE 12, 33
  329.        FOR i = 1 TO 15
  330.           COLOR colr(ABS(c \ 2 = c / 2) + 1), 2
  331.           IF c = 2 THEN c = 3 ELSE c = 2
  332.           PRINT MID$("La Belle Lucie ", i, 1);
  333.        NEXT
  334.        CALL delay18th(3): CALL keypress(i)
  335.    LOOP UNTIL i: CALL clrkbd
  336. ELSE
  337. LOCATE 12, 33: PRINT "La Belle Lucie"
  338. CALL getkey(0, i, i, i, i)
  339. END IF
  340. END SUB
  341.  
  342. SUB Shuffle STATIC
  343. FOR i = 1 TO cards: SWAP deck(i), deck(INT(RND * cards + 1)): NEXT
  344. FOR i = 1 TO cards \ 3: pile(i) = 3: NEXT
  345. pile(i) = cards MOD 3                          'last pile gets rest
  346. pile(i + 1) = 0                                'last pile marker
  347. END SUB
  348.  
  349.